# -*- coding: utf-8 -*-
from django.http import HttpResponseRedirect, Http404
from django.core.urlresolvers import reverse
from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404
from skoolmaster.general.common import render_template, maintainer_required, show_model_results_view, lecturer_or_administrator_required, check_lecturer_subjects
from skoolmaster.general.search import enrollment_student_search_logic, name_search_logic, student_search_logic
from skoolmaster.general.models import UserProfile, Enrollment
from skoolmaster.syllabus.models import UniversityProgram, Subject, FacultyModule, FacultyYear, SchoolYear
from skoolmaster.syllabus.forms import UniversityProgramForm, FacultyModuleForm, FacultyYearForm, SubjectForm, LecturersForm, ReportSubjectForm, SchoolYearForm, ReportEnrolledForm

@login_required
@lecturer_or_administrator_required
def report_enrolled(request):
  """
  Shows a report of students that have been enrolled according to specified
  criteria.
  """
  if request.GET.get('report'):
    form = ReportEnrolledForm(request.GET)
    if form.is_valid():
      school_year = form.cleaned_data.get('school_year')
      faculty_year = form.cleaned_data.get('faculty_year')
      university_program = form.cleaned_data.get('university_program')
      module = form.cleaned_data.get('module')
      enroll_type = form.cleaned_data.get('enroll_type')
      study_mode = form.cleaned_data.get('study_mode')
      filters = {}
      
      students = UserProfile.objects.filter(student_number__isnull = False)
      if school_year:
        filters['enrollment_forms__school_year'] = school_year
      if faculty_year:
        filters['enrollment_forms__study_year'] = faculty_year
      if university_program:
        filters['enrollment_forms__university_program'] = university_program
      if module:
        filters['enrollment_forms__modules'] = module
      if enroll_type and enroll_type != '0':
        filters['enrollment_forms__enrollment_type'] = enroll_type
      if study_mode and study_mode != '0':
        filters['enrollment_forms__study_mode'] = study_mode
      
      students = students.filter(**filters).distinct()
      return show_model_results_view(request, 'syllabus/reports/enrolled_students.html',
        queryset = students,
        fields = [
          { 'desc' : u"Vpisna št.", 'name' : 'student_number' },
          { 'desc' : u"Priimek", 'name' : 'surname' },
          { 'desc' : u"Ime", 'name' : 'name' }
        ],
        default_sort_field = "surname",
        show_search = True,
        search_logic = student_search_logic
      )
  else:
    form = ReportEnrolledForm()
  
  return render_template(request, 'syllabus/reports/enrolled_select.html', {
    'form' : form
  })

@login_required
@lecturer_or_administrator_required
def report_subject(request):
  """
  Shows a report of students that have selected the specified selective
  subject in the specified school year.
  """
  if request.GET.get('subject'):
    form = ReportSubjectForm(request.user, request.GET)
    if form.is_valid():
      school_years = form.cleaned_data.get('school_years')
      subject = form.cleaned_data.get('subject')
      check_lecturer_subjects(request, subject)
      
      # Find all students matching the criteria
      students = Enrollment.objects.filter(
        school_year__in = school_years,
        subjects = subject
      ).order_by("-school_year__name")
      
      return show_model_results_view(request, 'syllabus/reports/subject_students.html',
        queryset = students,
        fields = [
          { 'desc' : u"Vpisna št.", 'name' : '' },
          { 'desc' : u"Priimek", 'name' : '' },
          { 'desc' : u"Ime", 'name' : '' }
        ],
        show_search = True,
        search_logic = enrollment_student_search_logic,
        vars = {
          'school_years' : ", ".join([str(x) for x in school_years]),
          'subject' : subject
        }
      )
  else:
    form = ReportSubjectForm(request.user)
  
  return render_template(request, 'syllabus/reports/subject_select.html', {
    'form' : form
  })

# Default return address after some action
return_addr = lambda program_id: reverse('program_display', kwargs = {'program_id' : program_id})

@login_required
@maintainer_required
def program_management(request, program_id = None):
  """
  Main view for program management.
  """
  if program_id:
    try:
      program = UniversityProgram.objects.get(id = program_id)
    except:
      raise Http404
    
    return render_template(request, 'syllabus/program/display.html', {'program' : program, 'all_subjects' : Subject.objects.filter(disabled=False)})
  
  return show_model_results_view(request, 'syllabus/program/list.html',
    queryset = UniversityProgram.objects.all(),
    fields = [
      { 'desc' : u"Program", 'name' : "name" }
    ],
    show_search = True,
    search_logic = UniversityProgramForm.search_logic
  )

@login_required
@maintainer_required
def program_module_save(request, program_id, module_id):
  if request.method == 'POST':
    module = get_object_or_404(FacultyModule, pk = module_id)
    module.subjects.clear()
    for subject_id in request.POST.getlist('predmeti'):
      module.subjects.add(Subject.objects.get(pk = subject_id))
    module.save()
    request.user.message_set.create(message = u'0|Predmetnik shranjen.')
    
    return HttpResponseRedirect(return_addr(program_id))
  
@login_required
@maintainer_required
def program_elective_save(request, program_id, year_id):
  if request.method == 'POST':
    year = get_object_or_404(FacultyYear, pk = year_id)
    year.elective_subjects.clear()
    for subject_id in request.POST.getlist('predmeti'):
      year.elective_subjects.add(Subject.objects.get(pk = subject_id))
    year.save()
    request.user.message_set.create(message = u'0|Predmetnik shranjen.')
    
    return HttpResponseRedirect(return_addr(program_id))  

@login_required
@maintainer_required
def program_year(request, program_id, year_id = None):
  """
  Handles adding and deleting of faculty years.
  """
  name = 'letnik'
  # Handle add
  if not year_id:
    form = FacultyYearForm()
    if request.method == 'POST':
      # Add the year
      form = FacultyYearForm(request.POST)
      program = get_object_or_404(UniversityProgram, pk = program_id)
      year_exists = form['name'].data.upper() in map(lambda y: y.name, program.faculty_years.all())
      if form.is_valid() and not year_exists:
        year = form.save()
        program.faculty_years.add(year)
        request.user.message_set.create(message = u'0|Letnik uspešno dodan.')
        return HttpResponseRedirect(return_addr(program_id))
      elif year_exists:
        form._errors['name'] = u'V danem programu že obstaja ta letnik!'
    return render_template(request, 'syllabus/program/add.html', {'name' : name, 'form' : form })
  
  # Handle delete
  else:
    if request.method == 'POST':
       # Delete the selected year
      year = FacultyYear.objects.get(pk = year_id)
      # First delete all contained modules
      for module in year.modules.all():
        module.delete()
      year.delete()
      request.user.message_set.create(message = u'0|Letnik uspešno odstranjen.')
      return HttpResponseRedirect(return_addr(program_id))
    return render_template(request, 'syllabus/program/del.html', {'name' : name, 'item' : FacultyYear.objects.get(pk=year_id)}) 

@login_required
@maintainer_required
def program_module(request, program_id, year_id, module_id = None):
  """
  Handles adding and deleting of modules.
  """
  name = 'modul'
   # Handle add
  if not module_id:
    form = FacultyModuleForm()
    if request.method == 'POST':
      # Add the module
      form = FacultyModuleForm(request.POST)
      # Check for duplicates
      year = get_object_or_404(FacultyYear, pk = year_id)
      module_exists = form['name'].data.upper() in map(lambda y: y.name, year.modules.all())
      if form.is_valid() and not module_exists:
        module = form.save()
        FacultyYear.objects.get(pk = year_id).modules.add(module)
        request.user.message_set.create(message = u'0|Modul uspešno dodan.')
        return HttpResponseRedirect(return_addr(program_id))
      elif module_exists:
        form._errors['name'] = u'V danem letniku že obstaja modul s tem imenom!'
    return render_template(request, 'syllabus/program/add.html', {'name' : name, 'form' : form })
  
  # Handle delete
  else:
    if request.method == 'POST':
       # Delete the selected module
      module = FacultyModule.objects.get(pk = module_id)
      module.delete()
      request.user.message_set.create(message = u'0|Modul uspešno odstranjen.')
      return HttpResponseRedirect(return_addr(program_id))
    return render_template(request, 'syllabus/program/del.html', {'name' : name, 'item' : FacultyModule.objects.get(pk=module_id)})

@login_required
@maintainer_required  
def lecturers(request, subject_id = None):
  """
  Handles the managing of lecturers for a subject.
  """
  if subject_id:
    subject = get_object_or_404(Subject, pk = subject_id)
    form = LecturersForm(subject)
    if request.method == 'POST':
       # Save the selected lecturers
       form = LecturersForm(subject, request.POST)
       if form.is_valid():
         form.save()
         request.user.message_set.create(message = u'0|Izvajalci so uspešno spremenjeni.')

    return render_template(request, 'syllabus/edit_lecturers.html', {'form' : form, 'subject' : subject})
    
  return show_model_results_view(request, 'syllabus/subjects.html',
    queryset = Subject.objects.all(),
    fields = [
      { 'desc' : u"Predmet", 'name' : "name" },
      { 'desc' : u"Predavatelji", 'name' : "current_lecturers" }
    ],
    show_search = True,
    search_logic = name_search_logic
  )  

@maintainer_required
def school_year_display(request):
  """
  Display school year page.
  """
  queryset = SchoolYear.objects.all()
  return show_model_results_view(request, 'syllabus/school_year/school_years.html',
    queryset = queryset,
    fields = [
      { 'desc' : u"Šolsko leto", 'name' : "name" },
      { 'desc' : u"Uredi", 'name' : "" },
      { 'desc' : u"Briši", 'name' : "" }
    ],
    show_search = True,
    search_logic = SubjectForm.search_logic
  )

@maintainer_required
def school_year_edit(request, school_year_id, action):
  """
  Display school year page.
  """
  school_year = get_object_or_404(SchoolYear, pk = school_year_id)
  # Sanity check
  if school_year.enrollments.all(): 
    # No editing permited!
    raise Http404
  if action == 'edit':
    form = SchoolYearForm(instance = school_year, edit = True)
    if request.method == 'POST':
      form = SchoolYearForm(request.POST, instance = school_year, edit = True)
      if form.is_valid():
        form.save()
        request.user.message_set.create(message = u'0|Šolsko leto uspešno popravljeno.')
        return HttpResponseRedirect(reverse('school_year_display'))
    return render_template(request, 'syllabus/school_year/edit_school_year.html', {'form' : form })
  elif action == 'del':
    if request.method == 'POST':
      school_year.delete()
      request.user.message_set.create(message = u'0|Šolsko leto uspešno izbrisano.')
      return HttpResponseRedirect(reverse('school_year_display'))
    return render_template(request, 'syllabus/school_year/del_school_year.html', { 'school_year' : school_year })
  
@maintainer_required
def create_school_year(request):
  """
  Create a school year.
  """
  form = SchoolYearForm() 
  if request.method == 'POST':
    form = SchoolYearForm(request.POST)
    if form.is_valid():
      form.save()
      request.user.message_set.create(message = u'0|Šolsko leto uspešno ustvarjeno.')
      return HttpResponseRedirect(reverse('school_year_display'))
  return render_template(request, 'syllabus/school_year/create_school_year.html', {'form' : form })
